home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2b.lha / p4-1.2b / lib / p4_broadcast.c < prev    next >
C/C++ Source or Header  |  1993-02-06  |  11KB  |  545 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. #define MAXVAL(a,b) (((a)>(b)) ? (a) : (b))
  5. #define MINVAL(a,b) (((a)<(b)) ? (a) : (b))
  6. #define ABSVAL(a)   (((a)>=0 ) ? (a) : -(a))
  7.  
  8. static P4VOID init_p4_brdcst_info();
  9.  
  10. int p4_broadcastx(type, data, data_len, data_type)
  11. int type;
  12. char *data;
  13. int data_len, data_type;
  14. /*
  15.   Broadcast my data to all other processes.
  16.   Other processes call p4_recv() in the normal fashion, specifying
  17.   the node (if desired) that originated the broadcast.
  18. */
  19. {
  20.     int status = 0;
  21.     struct p4_msg *tmsg;
  22.  
  23.     init_p4_brdcst_info();
  24.  
  25.     /* Build the message with broadcast bit set */
  26.  
  27.     if (p4_get_my_id())
  28.     {                /* Not node 0 */
  29.     /*
  30.      * Send data to node 0. Recv internally discards broadcast message
  31.      * that is from the same process
  32.      */
  33.  
  34.     status = send_message(type, p4_get_my_id(), 0, data, data_len,
  35.                   data_type, P4_BROADCAST_MASK, FALSE);
  36.     }
  37.     else
  38.     {
  39.     /* I'm top of the tree ... start broadcast proper */
  40.  
  41.     status = subtree_broadcast_p4(type, p4_get_my_id(), data, data_len, data_type);
  42.     }
  43.  
  44.     if (status && !(SOFTERR))
  45.     p4_error("p4_broadcast failed, type=", type);
  46.  
  47.     return status;
  48. }
  49.  
  50. int subtree_broadcast_p4(type, from, data, data_len, data_type)
  51. char *data;
  52. int type, from, data_len, data_type;
  53. /*
  54.   Broadcast message to processes in my subtree.
  55.  
  56.   1) Send to left/right remote cluster masters
  57.   2) Send to left/right local  cluster slaves
  58. */
  59. {
  60.     int status = 0;
  61.     int size;
  62.     int nodes[4], i;
  63.     struct p4_msg *tmsg;
  64.  
  65.     init_p4_brdcst_info();
  66.  
  67.     p4_dprintfl(90, "subtree_broadcast_p4: type=%d, len=%d\n", type, data_len);
  68.  
  69.     nodes[0] = p4_brdcst_info.left_cluster;
  70.     nodes[1] = p4_brdcst_info.right_cluster;
  71.     nodes[2] = p4_brdcst_info.left_slave;
  72.     nodes[3] = p4_brdcst_info.right_slave;
  73.  
  74.     for (i = 0; i < 4; i++)
  75.     {
  76.     if (nodes[i] > 0)
  77.     {
  78.         if (send_message(type, from, nodes[i], data, data_len,
  79.                  data_type, P4_BROADCAST_MASK, FALSE))
  80.         {
  81.         status = -1;
  82.         break;
  83.         }
  84.     }
  85.     }
  86.  
  87.     if (status && !SOFTERR)
  88.     p4_error("subtree_broadcast_p4 failed, type+", tmsg->type);
  89.  
  90.     p4_dprintfl(90, "subtree_broadcast_p4: exit status=%d\n", status);
  91.     return status;
  92. }
  93.  
  94. static P4VOID init_p4_brdcst_info()
  95. /*
  96.   Construct tree connections for cluster-master and slave
  97.   processes and insert into global structure
  98. */
  99. {
  100. #define MAX_MASTERS P4_MAXPROCS
  101.     int me, my_master, node, n_master, indx = (-1);
  102.     int master_list[MAX_MASTERS], previous_id;
  103.  
  104.     if (p4_brdcst_info.initialized)    /* Only need to do this once */
  105.     return;
  106.  
  107.     p4_brdcst_info.initialized = 1;
  108.     p4_brdcst_info.up = -1;    /* -1 means no one there */
  109.     p4_brdcst_info.left_cluster = -1;
  110.     p4_brdcst_info.right_cluster = -1;
  111.     p4_brdcst_info.left_slave = -1;
  112.     p4_brdcst_info.right_slave = -1;
  113.  
  114.     me = p4_get_my_id();
  115.  
  116.     /* Make list of cluster masters and find my master */
  117.     /* Ideally should probably use p4_get_cluster_masters here */
  118.  
  119.     n_master = 0;
  120.     previous_id = -1;
  121.     for (node = 0; node < p4_num_total_ids(); node++)
  122.     {
  123.     if (p4_global->proctable[node].group_id != previous_id)
  124.     {
  125.         master_list[n_master++] = node;
  126.         previous_id = p4_global->proctable[node].group_id;
  127.     }
  128.     if (node == me)
  129.         indx = n_master - 1;
  130.     }
  131.     if (indx < 0)
  132.     p4_error("init_p4_brdcst_info: my master indx bad", indx);
  133.     my_master = master_list[indx];
  134.  
  135.     /*
  136.     printf("me=%d, indx=%d, n_master=%d, my_master=%d, myclusterid=%d, list=[",
  137.        me, indx, n_master, my_master, p4_get_my_cluster_id()); 
  138.     for (node=0; node<n_master; node++) 
  139.     printf(" %d",master_list[node]); 
  140.     printf(" ]\n");
  141.     */
  142.  
  143.     if (me == my_master)
  144.     {
  145.     /* If cluster master assign cluster master tree */
  146.  
  147.     if ((2 * indx + 1) < n_master)
  148.         p4_brdcst_info.left_cluster = master_list[2 * indx + 1];
  149.  
  150.     if ((2 * indx + 2) < n_master)
  151.         p4_brdcst_info.right_cluster = master_list[2 * indx + 2];
  152.  
  153.     if (me)
  154.         p4_brdcst_info.up = master_list[(indx - 1) / 2];
  155.     }
  156.  
  157.     /* Now assign connections with own subtree */
  158.     p4_dprintfl(90, "brdcst_info: numclusids=%d\n", p4_num_cluster_ids());
  159.     node = 2 * p4_get_my_cluster_id() + 1;
  160.     if (node < p4_num_cluster_ids())
  161.     p4_brdcst_info.left_slave = node + my_master;
  162.  
  163.     node = 2 * p4_get_my_cluster_id() + 2;
  164.     if (node < p4_num_cluster_ids())
  165.     p4_brdcst_info.right_slave = node + my_master;
  166.  
  167.     if (me != my_master)
  168.     p4_brdcst_info.up = my_master + (p4_get_my_cluster_id() - 1) / 2;
  169.  
  170.     p4_dprintfl(90, "brdcst_info: me=%d up=%d clusters(%d, %d) slaves(%d,%d)\n",
  171.         me,
  172.         p4_brdcst_info.up,
  173.         p4_brdcst_info.left_cluster,
  174.         p4_brdcst_info.right_cluster,
  175.         p4_brdcst_info.left_slave,
  176.         p4_brdcst_info.right_slave);
  177.  
  178.     /* Sanity check */
  179.  
  180.     if (p4_brdcst_info.up != -1)
  181.     if (CHECKNODE(p4_brdcst_info.up))
  182.         p4_error("init_p4_brdcst_info: up node is invalid", p4_brdcst_info.up);
  183.     if (p4_brdcst_info.left_cluster != -1)
  184.     if (CHECKNODE(p4_brdcst_info.left_cluster))
  185.         p4_error("init_p4_brdcst_info: left_cluster node is invalid",
  186.              p4_brdcst_info.left_cluster);
  187.     if (p4_brdcst_info.right_cluster != -1)
  188.     if (CHECKNODE(p4_brdcst_info.right_cluster))
  189.         p4_error("init_p4_brdcst_info: right_cluster node is invalid",
  190.              p4_brdcst_info.right_cluster);
  191.     if (p4_brdcst_info.left_slave != -1)
  192.     if (CHECKNODE(p4_brdcst_info.left_slave))
  193.         p4_error("init_p4_brdcst_info: left_slave node is invalid",
  194.              p4_brdcst_info.left_slave);
  195.     if (p4_brdcst_info.right_slave != -1)
  196.     if (CHECKNODE(p4_brdcst_info.right_slave))
  197.         p4_error("init_p4_brdcst_info: right_slave node is invalid",
  198.              p4_brdcst_info.right_slave);
  199. }
  200.  
  201.  
  202. int p4_global_op(type, x, nelem, size, op, data_type)
  203. int type;
  204. char *x;
  205. int nelem;
  206. int size;
  207. int data_type;
  208. P4VOID(*op) ();
  209. /* see userman for more details */
  210. {
  211.     int me = p4_get_my_id();
  212.     int status = 0;
  213.     int zero = 0;
  214.     int msg_len;
  215.     char *msg;
  216.  
  217.     init_p4_brdcst_info();
  218.  
  219.     /* Accumulate up broadcast tree ... mess is due to return of soft errors */
  220.  
  221.     if (!status)
  222.     if (p4_brdcst_info.left_slave > 0)
  223.     {
  224.         msg = NULL;
  225.         status = p4_recv(&type, &p4_brdcst_info.left_slave, &msg, &msg_len);
  226.         if (!status)
  227.         {
  228.         op(x, msg, msg_len / size);
  229.         p4_msg_free(msg);
  230.         }
  231.     }
  232.     if (!status)
  233.     if (p4_brdcst_info.right_slave > 0)
  234.     {
  235.         msg = NULL;
  236.         status = p4_recv(&type, &p4_brdcst_info.right_slave, &msg, &msg_len);
  237.         if (!status)
  238.         {
  239.         op(x, msg, msg_len / size);
  240.         p4_msg_free(msg);
  241.         }
  242.     }
  243.     if (!status)
  244.     if (p4_brdcst_info.left_cluster > 0)
  245.     {
  246.         msg = NULL;
  247.         status = p4_recv(&type, &p4_brdcst_info.left_cluster, &msg, &msg_len);
  248.         if (!status)
  249.         {
  250.         op(x, msg, msg_len / size);
  251.         p4_msg_free(msg);
  252.         }
  253.     }
  254.     if (!status)
  255.     if (p4_brdcst_info.right_cluster > 0)
  256.     {
  257.         msg = NULL;
  258.         status = p4_recv(&type, &p4_brdcst_info.right_cluster, &msg, &msg_len);
  259.         if (!status)
  260.         {
  261.         op(x, msg, msg_len / size);
  262.         p4_msg_free(msg);
  263.         }
  264.     }
  265.  
  266.     if ((!status) && p4_get_my_id())
  267.     status = p4_sendx(type, p4_brdcst_info.up, x, nelem * size, data_type);
  268.  
  269.     /* Broadcast the result back */
  270.  
  271.     if (!status)
  272.     {
  273.     if (me == 0)
  274.         status = p4_broadcastx(type, x, nelem * size, data_type);
  275.     else
  276.     {
  277.         msg = NULL;
  278.         status = p4_recv(&type, &zero, &msg, &msg_len);
  279.         if (!status)
  280.         {
  281.         bcopy(msg, (char *) x, msg_len);
  282.         p4_msg_free(msg);
  283.         }
  284.     }
  285.     }
  286.  
  287.     if (status && !SOFTERR)
  288.     p4_error("p4_global_op failed, type=", type);
  289.  
  290.     return status;
  291. }
  292.  
  293. /* Standard operations on doubles */
  294.  
  295. P4VOID p4_dbl_sum_op(x, y, nelem)
  296. char *x, *y;
  297. int nelem;
  298. {
  299.     double *a = (double *) x;
  300.     double *b = (double *) y;
  301.  
  302.     while (nelem--)
  303.     *a++ += *b++;
  304. }
  305.  
  306. P4VOID p4_dbl_mult_op(x, y, nelem)
  307. char *x, *y;
  308. int nelem;
  309. {
  310.     double *a = (double *) x;
  311.     double *b = (double *) y;
  312.  
  313.     while (nelem--)
  314.     *a++ *= *b++;
  315. }
  316.  
  317. P4VOID p4_dbl_max_op(x, y, nelem)
  318. char *x, *y;
  319. int nelem;
  320. {
  321.     double *a = (double *) x;
  322.     double *b = (double *) y;
  323.  
  324.     while (nelem--)
  325.     {
  326.     *a = MAXVAL(*a, *b);
  327.     a++;
  328.     b++;
  329.     }
  330. }
  331.  
  332. P4VOID p4_dbl_min_op(x, y, nelem)
  333. char *x, *y;
  334. int nelem;
  335. {
  336.     double *a = (double *) x;
  337.     double *b = (double *) y;
  338.  
  339.     while (nelem--)
  340.     {
  341.     *a = MINVAL(*a, *b);
  342.     a++;
  343.     b++;
  344.     }
  345. }
  346.  
  347. P4VOID p4_dbl_absmax_op(x, y, nelem)
  348. char *x, *y;
  349. int nelem;
  350. {
  351.     double *a = (double *) x;
  352.     double *b = (double *) y;
  353.  
  354.     while (nelem--)
  355.     {
  356.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  357.     a++;
  358.     b++;
  359.     }
  360. }
  361.  
  362. P4VOID p4_dbl_absmin_op(x, y, nelem)
  363. char *x, *y;
  364. int nelem;
  365. {
  366.     double *a = (double *) x;
  367.     double *b = (double *) y;
  368.  
  369.     while (nelem--)
  370.     {
  371.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  372.     a++;
  373.     b++;
  374.     }
  375. }
  376.  
  377. /* Standard operations on floats */
  378.  
  379. P4VOID p4_flt_sum_op(x, y, nelem)
  380. char *x, *y;
  381. int nelem;
  382. {
  383.     float *a = (float *) x;
  384.     float *b = (float *) y;
  385.  
  386.     while (nelem--)
  387.     *a++ += *b++;
  388. }
  389.  
  390. P4VOID p4_flt_mult_op(x, y, nelem)
  391. char *x, *y;
  392. int nelem;
  393. {
  394.     float *a = (float *) x;
  395.     float *b = (float *) y;
  396.  
  397.     while (nelem--)
  398.     *a++ *= *b++;
  399. }
  400.  
  401. P4VOID p4_flt_max_op(x, y, nelem)
  402. char *x, *y;
  403. int nelem;
  404. {
  405.     float *a = (float *) x;
  406.     float *b = (float *) y;
  407.  
  408.     while (nelem--)
  409.     {
  410.     *a = MAXVAL(*a, *b);
  411.     a++;
  412.     b++;
  413.     }
  414. }
  415.  
  416. P4VOID p4_flt_min_op(x, y, nelem)
  417. char *x, *y;
  418. int nelem;
  419. {
  420.     float *a = (float *) x;
  421.     float *b = (float *) y;
  422.  
  423.     while (nelem--)
  424.     {
  425.     *a = MINVAL(*a, *b);
  426.     a++;
  427.     b++;
  428.     }
  429. }
  430.  
  431. P4VOID p4_flt_absmax_op(x, y, nelem)
  432. char *x, *y;
  433. int nelem;
  434. {
  435.     float *a = (float *) x;
  436.     float *b = (float *) y;
  437.  
  438.     while (nelem--)
  439.     {
  440.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  441.     a++;
  442.     b++;
  443.     }
  444. }
  445.  
  446. P4VOID p4_flt_absmin_op(x, y, nelem)
  447. char *x, *y;
  448. int nelem;
  449. {
  450.     float *a = (float *) x;
  451.     float *b = (float *) y;
  452.  
  453.     while (nelem--)
  454.     {
  455.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  456.     a++;
  457.     b++;
  458.     }
  459. }
  460.  
  461.  
  462. /* Standard operations on integers */
  463.  
  464. P4VOID p4_int_sum_op(x, y, nelem)
  465. char *x, *y;
  466. int nelem;
  467. {
  468.     int *a = (int *) x;
  469.     int *b = (int *) y;
  470.  
  471.     while (nelem--)
  472.     *a++ += *b++;
  473. }
  474.  
  475. P4VOID p4_int_mult_op(x, y, nelem)
  476. char *x, *y;
  477. int nelem;
  478. {
  479.     int *a = (int *) x;
  480.     int *b = (int *) y;
  481.  
  482.     while (nelem--)
  483.     *a++ *= *b++;
  484. }
  485.  
  486. P4VOID p4_int_max_op(x, y, nelem)
  487. char *x, *y;
  488. int nelem;
  489. {
  490.     int *a = (int *) x;
  491.     int *b = (int *) y;
  492.  
  493.     while (nelem--)
  494.     {
  495.     *a = MAXVAL(*a, *b);
  496.     a++;
  497.     b++;
  498.     }
  499. }
  500.  
  501. P4VOID p4_int_min_op(x, y, nelem)
  502. char *x, *y;
  503. int nelem;
  504. {
  505.     int *a = (int *) x;
  506.     int *b = (int *) y;
  507.  
  508.     while (nelem--)
  509.     {
  510.     *a = MINVAL(*a, *b);
  511.     a++;
  512.     b++;
  513.     }
  514. }
  515.  
  516. P4VOID p4_int_absmax_op(x, y, nelem)
  517. char *x, *y;
  518. int nelem;
  519. {
  520.     int *a = (int *) x;
  521.     int *b = (int *) y;
  522.  
  523.     while (nelem--)
  524.     {
  525.     *a = MAXVAL(ABSVAL(*a), ABSVAL(*b));
  526.     a++;
  527.     b++;
  528.     }
  529. }
  530.  
  531. P4VOID p4_int_absmin_op(x, y, nelem)
  532. char *x, *y;
  533. int nelem;
  534. {
  535.     int *a = (int *) x;
  536.     int *b = (int *) y;
  537.  
  538.     while (nelem--)
  539.     {
  540.     *a = MINVAL(ABSVAL(*a), ABSVAL(*b));
  541.     a++;
  542.     b++;
  543.     }
  544. }
  545.